﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using QAAdmin.BusinessObject;

namespace QAAdmin.UI
{
    public partial class frmPenugasan : BaseForm
    {
        public enum Mode
        {
            New,
            Modify
        }

        // Declare our worker thread
        private BackgroundWorker bwAcak = new BackgroundWorker();
        private bool modeacak;

        private Mode mode;
        private TipeSPT tipe;
        //default 1;
        private double persentase = 1;
        private IList<QAJob> lstJob;
        private IList<Petugas> lstPetugas;

        public IList<QAJob> ListJob
        {
            get { return lstJob; }
            set { lstJob = value; }
        }

        public frmPenugasan(Mode mode)
        {
            InitializeComponent();
            this.tipe = QAController.TipeSPT;
            this.mode = mode;
            this.Text += " (" + tipe + ")";
        }

        private void frmPenugasan_Load(object sender, EventArgs e)
        {
            try
            {
                int jumlahSPT = 0;
                if (mode == Mode.New)
                {
                    frmJumlahSPT f = new frmJumlahSPT();
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        int.TryParse(f.txtJumlahSPT.Text, out jumlahSPT);
                    }
                }
                //double dPersentase = 1;
                string sPersentase = System.Configuration.ConfigurationManager.AppSettings["PersentaseBalance"];
                double.TryParse(sPersentase, out persentase);
                this.Cursor = Cursors.WaitCursor;

                if (mode == Mode.New)
                {
                    if (tipe == TipeSPT.Balance)
                    {
                        //frmPersentase fp = new frmPersentase();
                        //fp.ShowDialog();
                        persentase = (double)persentase / 100.0;
                        lstJob = QAController.GetNewBalancedJob(persentase, jumlahSPT);
                    }
                    else
                        lstJob = QAController.GetNewUnbalancedJob(jumlahSPT);
                }
                lstNewJob.Items.Clear();
                foreach (QAJob j in lstJob)                    
                    lstNewJob.Items.Add(j);                

                if (tipe == TipeSPT.Balance)
                    lstPetugas = QAController.GetBalancedPetugas();
                else
                    lstPetugas = QAController.GetUnbalancedPetugas();

                cmbPetugas.Items.Clear();
                foreach (Petugas p in lstPetugas)
                    cmbPetugas.Items.Add(p);
                if (cmbPetugas.Items.Count > 0)
                    cmbPetugas.SelectedIndex = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void btnR_Click(object sender, EventArgs e)
        {
            if (lstNewJob.SelectedItems.Count == 0)
            {
                ShowMessageboxNoDataDipilih();
                return;
            }
            else if (cmbPetugas.SelectedIndex < 0)
            {
                ShowMessageboxNoPetugas();
                return;
            }

            List<QAJob> lstJob = new List<QAJob>();
            Petugas p = cmbPetugas.SelectedItem as Petugas;
            for (int i = 0; i < lstNewJob.SelectedItems.Count; i++)
            {
                QAJob j = lstNewJob.SelectedItems[i] as QAJob;
                p.DaftarQAJob.Add(j);
                lstJob.Add(j);
            }

            foreach (QAJob j in lstJob)
                lstNewJob.Items.Remove(j);

            RefreshAssignedJob();
        }

        private void btnL_Click(object sender, EventArgs e)
        {
            if (lstAssignedJob.SelectedItems.Count == 0)
            {
                ShowMessageboxNoDataDipilih();
                return;
            }

            Petugas p = cmbPetugas.SelectedItem as Petugas;
            for (int i = 0; i < lstAssignedJob.SelectedItems.Count; i++)
            {
                QAJob j = lstAssignedJob.SelectedItems[i] as QAJob;
                p.DaftarQAJob.Remove(j);
                lstNewJob.Items.Add(j);
            }

            RefreshAssignedJob();
        }

        private void btnRR_Click(object sender, EventArgs e)
        {
            if (lstNewJob.Items.Count == 0)
            {
                MessageBox.Show("Tidak ada data pada daftar sebelah kiri", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else if (cmbPetugas.SelectedIndex < 0)
            {
                ShowMessageboxNoPetugas();
                return;
            }

            Petugas p = cmbPetugas.SelectedItem as Petugas;
            foreach (QAJob j in lstNewJob.Items)
                p.DaftarQAJob.Add(j);

            lstNewJob.Items.Clear();

            RefreshAssignedJob();
        }

        private void btnLL_Click(object sender, EventArgs e)
        {
            if (lstAssignedJob.Items.Count == 0)
            {
                MessageBox.Show("Tidak ada data pada daftar sebelah kanan", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Petugas p = cmbPetugas.SelectedItem as Petugas;
            foreach (QAJob j in lstAssignedJob.Items)
                lstNewJob.Items.Add(j);

            p.DaftarQAJob.Clear();

            RefreshAssignedJob();
        }

        private void RefreshAssignedJob()
        {
            try
            {
                this.Cursor = Cursors.AppStarting;
                if (modeacak) return;
                if (cmbPetugas.SelectedIndex < 0) return;

                Petugas p = cmbPetugas.SelectedItem as Petugas;
                lstAssignedJob.Items.Clear();
                foreach (QAJob j in p.DaftarQAJob)
                    lstAssignedJob.Items.Add(j);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void ShowMessageboxNoPetugas()
        {
            MessageBox.Show("Anda harus memilih petugas yang akan menerima penugasan", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void ShowMessageboxNoDataDipilih()
        {
            MessageBox.Show("Tidak ada data yang dipilih", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void cmbPetugas_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshAssignedJob();
        }

        private void btnSimpan_Click(object sender, EventArgs e)
        {
            string msg = "Anda yakin akan menyimpan pembagian tugas yang telah Anda lakukan?";
            if (MessageBox.Show(msg, this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
                return;

            List<QAJob> lstJob = new List<QAJob>();
            Guid guid = Guid.NewGuid();
            DateTime now = DateTime.Now;
            foreach (Petugas p in cmbPetugas.Items)
            {                
                foreach (QAJob j in p.DaftarQAJob)
                {
                    QAJob job = QAController.GetJobByDocIdAndBarcode(j.DocId, j.Barcode);
                    if (job!=null)
                    {
                        j.StatusAsal = job.StatusAkhir;
                        j.Catatan = job.Catatan + Environment.NewLine;
                        QAController.DeleteJob(job);
                    }
                    else
                        j.StatusAsal = this.tipe.ToString().ToLower();
                    j.WaktuPenugasan = now;
                    j.JobID = guid.ToString();
                    j.DitugaskanKepada = p.Username;                    
                    j.Catatan = DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " oleh " + QAController.Username + " ditugaskan kepada " + p.Username + Environment.NewLine + j.Catatan;
                    j.JenisSPT = j.JenisSPT;
                    lstJob.Add(j);

                    //if (mode == Mode.Modify)
                        //QAController.DeleteJob(j.DocId);
                }
            }

            QAController.CreateNewJobs(lstJob);

            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }


        private void btnRandom_Click(object sender, EventArgs e)
        {
            try
            {
                this.Cursor = Cursors.AppStarting;
                modeacak = true;
                if (cmbPetugas.Items.Count > 0)
                {
                    Random random = new Random();
                    int iNewJobCount = lstNewJob.Items.Count;
                    List<int> listOfficer = GetRandomNumbers(cmbPetugas.Items.Count, cmbPetugas.Items.Count);
                    for (int i = 0; i < iNewJobCount; i++)
                    {
                        lstNewJob.ClearSelected();
                        if (lstNewJob.Items.Count > 0)
                        {
                            lstNewJob.SelectedIndex = 0;                            
                           // if (cmbPetugas.SelectedIndex + 2 > cmbPetugas.Items.Count)
                            //    cmbPetugas.SelectedIndex = 0;
                            //else
                            //    cmbPetugas.SelectedIndex++;
                            cmbPetugas.SelectedIndex = listOfficer.IndexOf(i % cmbPetugas.Items.Count);
                            btnR_Click(new object(), new EventArgs());
                        }
                    }
                }
                modeacak = false;
                RefreshAssignedJob();
            }
            finally
            {
                modeacak = false;
                this.Cursor = Cursors.Default;                
            }
            /* bwAcak.WorkerReportsProgress = true;
             bwAcak.WorkerSupportsCancellation = true;
             bwAcak.DoWork += new DoWorkEventHandler(bwAcak_DoWork);
             bwAcak.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwAcak_RunWorkerCompleted);

             try
             {
                 bwAcak.RunWorkerAsync();

             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }*/
        }

        void bwAcak_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RefreshAssignedJob();
        }

        void bwAcak_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                this.Cursor = Cursors.AppStarting;
                modeacak = true;
                Random random = new Random();
                int iNewJobCount = lstNewJob.Items.Count;
                List<int> listOfficer = GetRandomNumbers(cmbPetugas.Items.Count, cmbPetugas.Items.Count);
                for (int i = 0; i < iNewJobCount; i++)
                {
                    if (lstNewJob.Items.Count > 0)
                    {
                        if (this.lstNewJob.InvokeRequired)
                        {
                            this.Invoke((MethodInvoker)delegate
                            {
                                lstNewJob.SelectedIndex = 0;
                                cmbPetugas.SelectedIndex = listOfficer.IndexOf(i % cmbPetugas.Items.Count);
                                btnR_Click(new object(), new EventArgs());
                            });
                        }
                    }
                }
                modeacak = false;
            }
            finally
            {
                modeacak = false;
                this.Cursor = Cursors.Default;
            }
        }

        internal List<int> GetRandomNumbers(int noOfRandomNumbers, int maxValue)
        {
            var mySet = new HashSet<int>();
            List<int> ret = new List<int>();
            for (int i = 0; i < noOfRandomNumbers; i++)
            {
                int randomNo = new Random().Next(maxValue);

                while (!mySet.Add(randomNo))
                {
                    randomNo = new Random().Next(maxValue);
                }
                ret.Add(randomNo);
            }
            return ret;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshAssignedJob();
        }
    }
}
